/**
 * Project Name:pay-protocol
 * File Name:Xml.java
 * Package Name:cn.swiftpass.pay.protocol
 * Date:2014-8-10下午10:48:21
 */

package com.acooly.module.openapi.client.provider.allinpay.utils;

import com.acooly.core.common.exception.BusinessException;
import com.acooly.module.openapi.client.api.exception.ApiClientException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;
import com.thoughtworks.xstream.security.NoTypePermission;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.util.TextUtils;
import org.dom4j.Element;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ClassName:Xml
 * Function: XML的工具方法
 * Date:     2014-8-10 下午10:48:21
 *
 * @author
 */
@Slf4j
public class XmlUtils {

    private static final String XML_HEAD = "<?xml version=\"1.0\" encoding=\"GBK\"?>";

    /**
     * 转MAP
     *
     * @param element
     * @return
     * @author
     */
    public static Map<String, String> toMap(Element element) {
        Map<String, String> rest = new HashMap<String, String>();
        List<Element> els = element.elements();
        for (Element el : els) {
            rest.put(el.getName().toLowerCase(), el.getTextTrim());
        }
        return rest;
    }

    /**
     * 利用xStream将xml报文转化为实体
     *
     * @param xmlStr
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T toBean(String xmlStr, Class<T> cls) {
        if (TextUtils.isEmpty(xmlStr) || xmlStr.contains("Error")) {
            return null;
        }
        try {
            XStream xstream = new XStream(new DomDriver());
//            XStream.setupDefaultSecurity(xstream);
            xstream.addPermission(AnyTypePermission.ANY);
            xstream.addPermission(NoTypePermission.NONE);
            //忽略不需要的节点
            xstream.ignoreUnknownElements();
            //对指定的类使用Annotations 进行序列化
            xstream.processAnnotations(cls);
            xstream.allowTypes(new Class[]{cls});
            T obj = (T) xstream.fromXML(xmlStr);
            return obj;
        } catch (Exception e) {
            throw new ApiClientException("响应报文转化失败："+e.getMessage());
        }
    }

    /**
     * 利用xStream将实体报文转化为xml
     *
     * @param obj
     * @return
     */
    public static String toXml(Object obj,boolean isSign) {
        try {
            XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));
            //1.4.10配置安全框架
            XStream.setupDefaultSecurity(xstream);
            //忽略不需要的节点
            xstream.ignoreUnknownElements();
            //对指定的类使用Annotations 进行序列化
            xstream.processAnnotations(obj.getClass());
            xstream.aliasSystemAttribute(null, "class");
            String returnXml = xstream.toXML(obj);
            if(isSign) {
                String IDD_STR="<SIGNED_MSG>sign</SIGNED_MSG>";
                if(returnXml.indexOf(IDD_STR) == -1){
                    throw new BusinessException("找不到签名信息字段");
                }
                returnXml = returnXml.replaceAll(IDD_STR, "");
            }
            return XML_HEAD+returnXml;
        } catch (Exception e) {
            throw new ApiClientException("请求报文转化失败："+e.getMessage());
        }
    }

}

